-module(dlq).
-author("iamapo").
-import(werkzeug, [get_config_value/2, logging/2, to_String/1, timeMilliSecond/0]).

%% API
-export([createNew/0, get/2, add/3, getMaxNumber/1, getMinNumber/1]).


createNew() ->
  [].

% Gibt Nachricht für die Nummer aus
get(Nummer, DeliveryQueue) ->
  %werkzeug:logging("NServer.log", lists:concat(["DeliveryQueue GET: ", "", " Nummer ", werkzeug:to_String(Nummer), "\n"])),
  proplists:get_value(Nummer, DeliveryQueue, messageNotInDLQ)
.

%anhaengen einer Nachricht an die DLQ
%wenn dlq zu groß werden würde wird kleinste nachricht geloescht
%danach wird dlq nach nummer sortiert
add(Nachricht, Nummer, DeliveryQueue) ->
  %werkzeug:logging("NServer.log", lists:concat(["DeliveryQueue ADD: ", "", " Nummer ", werkzeug:to_String(Nummer), "\n"])),
  {ok, ConfigListe} = file:consult("server.cfg"),
  {ok, DeliveryQueueMaxSize} = get_config_value(dlqlimit, ConfigListe),
  Message = lists:concat([Nachricht, " DLQ In: ", werkzeug:timeMilliSecond()]),
  NewDeliveryQueue = lists:keysort(1, [{Nummer, Message} | holdDlqLimit(DeliveryQueue, DeliveryQueueMaxSize)]),
  NewDeliveryQueue
.

%gibt kleinste nummer in DLQ wieder
% wenn dlq leer retun 0
getMinNumber([]) -> 0;
getMinNumber(DeliveryQueue) -> lists:min(proplists:get_keys(DeliveryQueue)).

%gibt groeßte nummer in DLQ wieder
% wenn dlq leer retun 0
getMaxNumber([]) -> 0;
getMaxNumber(DeliveryQueue) -> lists:max(proplists:get_keys(DeliveryQueue)).

% Loescht so lange die Nachrichten mit der kleinsten NachrichtenId
% aus der DLQ, damit Platz für die neue Nachricht ist
holdDlqLimit(DeliveryQueue, DeliveryQueueMaxSize) ->
  case length(DeliveryQueue) + 1 >= DeliveryQueueMaxSize of
    false -> DeliveryQueue;
    true ->
      MinNr = getMinNumber(DeliveryQueue),
      werkzeug:logging("NServer.log", lists:concat(["<<<< Message in DLQ und >>>>>: Nachricht [", to_String(MinNr), "] aus DLQ geloescht. \n"])),
      holdDlqLimit(proplists:delete(MinNr, DeliveryQueue), DeliveryQueueMaxSize)
  end.